package com.huahai.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huahai.annotation.AuthCheck;
import com.huahai.common.BaseResponse;
import com.huahai.common.DeleteRequest;
import com.huahai.constant.UserConstant;
import com.huahai.exception.ErrorCode;
import com.huahai.pojo.dto.barrage.BarrageAddDTO;
import com.huahai.pojo.dto.barrage.BarrageQueryDTO;
import com.huahai.pojo.dto.barrage.BarrageUpdateDTO;
import com.huahai.pojo.entity.Barrage;
import com.huahai.pojo.entity.User;
import com.huahai.pojo.vo.barrage.BarrageVO;
import com.huahai.service.BarrageService;
import com.huahai.service.UserService;
import com.huahai.util.ResultUtils;
import com.huahai.util.ThrowUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 弹幕控制层
 *
 * @author huahai
 */
@RestController
@RequestMapping("/barrage")
@Slf4j
public class BarrageController {

    @Resource
    private BarrageService barrageService;

    @Resource
    private UserService userService;

    /**
     * 添加弹幕
     *
     * @param barrageAddDTO
     * @param request
     * @return
     */
    @PostMapping("/add")
    @ApiOperation("添加弹幕")
    public BaseResponse<Long> addBarrage(@RequestBody BarrageAddDTO barrageAddDTO, HttpServletRequest request) {
        ThrowUtils.throwIf(barrageAddDTO == null, ErrorCode.PARAMS_ERROR);
        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        Long barrageId = barrageService.addBarrage(barrageAddDTO, loginUser);
        return ResultUtils.success(barrageId);
    }

    /**
     * 删除弹幕
     *
     * @param deleteRequest
     * @param request
     * @return 删除结果
     */
    @PostMapping("/delete")
    @ApiOperation("删除弹幕")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteBarrage(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(deleteRequest == null, ErrorCode.PARAMS_ERROR);
        Long id = deleteRequest.getId();
        ThrowUtils.throwIf(id == null || id <= 0, ErrorCode.PARAMS_ERROR);
        Barrage barrage = barrageService.getById(id);
        ThrowUtils.throwIf(barrage == null, ErrorCode.NOT_FOUND_ERROR, "弹幕不存在");
        // 执行删除弹幕
        boolean deleteResult = barrageService.removeById(barrage);
        ThrowUtils.throwIf(!deleteResult, ErrorCode.OPERATION_ERROR, "删除弹幕失败");
        return ResultUtils.success(true);
    }

    /**
     * 修改弹幕
     *
     * @param barrageUpdateDTO
     * @param request
     * @return 修改结果
     */
    @PostMapping("/update")
    @ApiOperation("修改弹幕")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateBarrage(@RequestBody BarrageUpdateDTO barrageUpdateDTO, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(barrageUpdateDTO == null, ErrorCode.PARAMS_ERROR);
        Long id = barrageUpdateDTO.getId();
        ThrowUtils.throwIf(id == null || id <= 0, ErrorCode.PARAMS_ERROR);
        Barrage barrage = barrageService.getById(id);
        ThrowUtils.throwIf(barrage == null, ErrorCode.NOT_FOUND_ERROR, "弹幕不存在");
        String newContent = barrageUpdateDTO.getContent();
        // 执行更新
        barrage.setContent(newContent);
        barrageService.validBarrage(barrage);
        boolean updateResult = barrageService.updateById(barrage);
        ThrowUtils.throwIf(!updateResult, ErrorCode.OPERATION_ERROR, "更新失败");
        return ResultUtils.success(true);
    }

    /**
     * 根据 id 获取弹幕（仅管理员可用）
     *
     * @param id      弹幕 id
     * @param request 请求
     * @return 弹幕信息
     */
    @ApiOperation(value = "根据 id 获取完整弹幕信息(管理员)")
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Barrage> getBarrageById(long id, HttpServletRequest request) {
        // 1. 校验参数
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 2. 查询数据库
        Barrage barrage = barrageService.getById(id);
        ThrowUtils.throwIf(barrage == null, ErrorCode.NOT_FOUND_ERROR);
        // 3. 获取封装类,不脱敏的弹幕信息
        return ResultUtils.success(barrage);
    }
    
    /**
     * 根据 id 获取弹幕（封装类 管理员可用）
     *
     * @param id      弹幕 id
     * @param request 请求
     * @return 脱敏的弹幕信息
     */
    @ApiOperation(value = "根据 id 获取封装后的弹幕")
    @GetMapping("/get/vo")
    public BaseResponse<BarrageVO> getBarrageVOById(long id, HttpServletRequest request) {
        // 1. 校验参数
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 2. 查询数据库
        Barrage barrage = barrageService.getById(id);
        ThrowUtils.throwIf(barrage == null, ErrorCode.NOT_FOUND_ERROR);
        // 3. 给前端返回当前登录用户具有的权限
        BarrageVO barrageVO = barrageService.getBarrageVO(barrage, request);
        // 4. 返回结果
        return ResultUtils.success(barrageVO);
    }

    /**
     * 分页获取未脱敏弹幕列表（仅管理员可用）
     *
     * @param barrageQueryDTO 弹幕查询参数
     * @return 弹幕列表
     */
    @ApiOperation(value = "分页获取未脱敏弹幕列表(管理员)")
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Barrage>> listBarrageByPage(@RequestBody BarrageQueryDTO barrageQueryDTO) {
        // 1. 获取分页参数
        long current = barrageQueryDTO.getCurrent();
        long size = barrageQueryDTO.getPageSize();
        // 2. 查询数据库
        Page<Barrage> barragePage = barrageService.page(new Page<>(current, size), barrageService.getQueryWrapper(barrageQueryDTO));
        // 3. 返回不脱敏的弹幕信息列表
        return ResultUtils.success(barragePage);
    }

    /**
     * 分页获取弹幕列表（封装类）
     *
     * @param barrageQueryDTO 弹幕查询参数
     * @param request       请求
     * @return 分页后的脱敏弹幕列表
     */
    @ApiOperation(value = "分页获取脱敏后的弹幕列表")
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<BarrageVO>> listBarrageVOByPage(@RequestBody BarrageQueryDTO barrageQueryDTO, HttpServletRequest request) {
        // 1. 获取分页参数
        long current = barrageQueryDTO.getCurrent();
        long size = barrageQueryDTO.getPageSize();
        // 2. 定义一次性最大获取弹幕数量，限制爬虫
        ThrowUtils.throwIf(size > 70, ErrorCode.PARAMS_ERROR, "获取弹幕数量超过限制！");
        // 3. 查询数据库
        Page<Barrage> barragePage = barrageService.page(new Page<>(current, size), barrageService.getQueryWrapper(barrageQueryDTO));
        // 4. 获取封装类并返回
        return ResultUtils.success(barrageService.getBarrageVOPage(barragePage, request));
    }
}
